/* * JSane * * Copyright 2004 - 2006 Andi McLean * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package uk.org.jsane.JSane_Net; import java.io.IOException; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Vector; import uk.org.jsane.JSane_Base.JSane_Base_Connection; import uk.org.jsane.JSane_Base.JSane_Base_Device; import uk.org.jsane.JSane_Base.JSane_Base_Type; import uk.org.jsane.JSane_Base.JSane_Base_Type_String; import uk.org.jsane.JSane_Base.JSane_Base_Type_Word; import uk.org.jsane.JSane_Exceptions.JSane_Exception; /** * * @author Andi McLean * * The main class that needs to be created, before commucation with saned */ public class JSane_Net_Connection extends JSane_Base_Connection { /** Version of the sane net protocol we know about */ public static int V_MAJOR = 1; public static int V_MINOR = 0; public static int SANEI_NET_PROTOCOL_VERSION = 3; /** Procedure numbers used in the sane net protocol */ private static int SANE_NET_INIT = 0; private static int SANE_NET_GET_DEVICES = 1; private static int SANE_NET_OPEN = 2; private static int SANE_NET_CLOSE = 3; private static int SANE_NET_GET_OPTION_DESCRIPTORS = 4; private static int SANE_NET_CONTROL_OPTION = 5; private static int SANE_NET_GET_PARAMETERS = 6; private static int SANE_NET_START = 7; private static int SANE_NET_CANCEL = 8; private static int SANE_NET_AUTHORIZE = 9; private static int SANE_NET_EXIT = 10; /* The current wire to saned */ protected JSane_Wire _wire = null; /* A list of devices that are know to saned */ protected Get_devices_reply _devices = null; private String _hostname; // Used to open a second socket to get the image data. /** * Constructor. * @param hostname The name of the host to connect to. * @param port The port of the host to connect to. * * date author reason * 09/Dec/03 am Initial version. */ public JSane_Net_Connection( String hostname , int port ) throws IOException , UnknownHostException { super(); _wire = new JSane_Wire_Binary( hostname , port ); _hostname = hostname; net_init(); } /** * Get the number of devices that saned knows about. * * @return The number of devices. * * date author reason * 09/Dec/03 am Initial version. */ public int getNumberDevices() throws JSane_Exception , IOException { if ( _devices == null ) { _devices = net_get_devices(); } if ( _devices.status != SANE_STATUS_GOOD ) { int sta = _devices.status; throw JSane_Exception.getException( sta ); } if ( _devicesMap == null ) { _devicesMap = new HashMap(); for ( int loop = 0; loop < _devices.devices.size(); ++loop ) { if ( _devices.devices.elementAt( loop ) != null ) { String name = ((JSane_Base_Device) _devices.devices.elementAt( loop )) .getName() .toUpperCase(); _devicesMap.put( name , _devices.devices.elementAt( loop ) ); } } } return _devices.devices.size(); } /** * Gets a device saned knows about. * @param pos the index of the device as returned by getDevices * @return null - if pos is out of range. else the device * * date author reason * 09/Dec/03 am Initial version. */ public JSane_Base_Device getDevice( int pos ) throws JSane_Exception , IOException { if ( pos >= 0 && pos < getNumberDevices() ) { return (JSane_Net_Device) _devices.devices.elementAt( pos ); } return null; } /** * Gets a device given it's name. * @param device The name of the device to open. Not case sensitive. * @return Null if no device was found with given name else the requested device. * * date author reason * 09/Dec/03 am Initial version. */ public JSane_Base_Device getDevice( String device ) throws JSane_Exception , IOException { if ( getNumberDevices() > 0 ) { return (JSane_Net_Device) _devicesMap.get( device.toUpperCase() ); } return null; } /** * Calls the Init function on saned. This should be the first function called. * @return status The status from the call. * * date author reason * 09/Dec/03 am Initial version. */ protected int net_init() throws IOException { _wire.sendWord( SANE_NET_INIT ); _wire.sendWord( SANE_VERSION_CODE( V_MAJOR , V_MINOR , SANEI_NET_PROTOCOL_VERSION ) ); _wire.sendString( System.getProperty( "user.name" ) ); int status = _wire.getWord(); int version = _wire.getWord(); return status; } /** * Retrive the devices from saned. * @return the status and devices from saned. * * date author reason * 09/Dec/03 am Initial version. */ protected Get_devices_reply net_get_devices() throws IOException { Get_devices_reply reply = new Get_devices_reply(); _wire.sendWord( SANE_NET_GET_DEVICES ); reply.status = _wire.getWord(); JSane_Net_Device dev = new JSane_Net_Device( this ); reply.devices = _wire.getPtrArray( dev ); return reply; } /** * Call to the function Net_Open on saned. * Used by {@link} JSane_Net_Device.open() * @param device_name the name of the device to be opened. * @return the data returned from saned. * * date author reason * 09/Dec/03 am Initial version. */ protected Net_open_reply net_open( JSane_Net_Type_String device_name ) throws IOException { Net_open_reply reply = new Net_open_reply(); _wire.sendWord( SANE_NET_OPEN ); device_name._sendElement( _wire ); reply.status = _wire.getWord(); reply.handle._getElement( _wire ); reply.resource._getElement( _wire ); return reply; } /** * * @author weirdpanda * *Copyright 2001, 2002,2003 Andi McLean * * The data returned from a call to net_open function on saned. * * status - the status of the call. * handle - the handle associated with the device. * resource - The resource that needs to be authorised. (Not yet used) * * date author reason * 09/Dec/03 am Initial version. */ protected class Net_open_reply { public int status = 0; public JSane_Net_Type_Word handle = new JSane_Net_Type_Word(); public JSane_Net_Type_String resource = new JSane_Net_Type_String(); } /** * Closes a device on saned. After calling this the handle can no longer be used. * * @param handle The handle of the device as returned by {@link}net_open. * * date author reason * 09/Dec/03 am Initial version. */ protected void net_close( JSane_Net_Type_Word handle ) throws IOException { _wire.sendWord( SANE_NET_CLOSE ); handle._sendElement( _wire ); _wire.getWord(); } /** * Returns the desctiptors of the options from saned. * @param device - The device to get the options for. * @return the data returned from saned. * * date author reason * 09/Dec/03 am Initial version. */ protected Vector net_get_option_descriptors( JSane_Net_Device device ) throws IOException { _wire.sendWord( SANE_NET_GET_OPTION_DESCRIPTORS ); device._getHandle()._sendElement( _wire ); Vector vec = _wire.getPtrArray( new JSane_Net_Option_Type_Descriptor( device ) ); for ( int loop = 0; loop < vec.size(); ++loop ) { if ( vec.elementAt( loop ) != null ) { ((JSane_Net_Option_Type_Descriptor) vec.elementAt( loop )) .setOptionNumber( loop ); } } return vec; } /** * Sets and gets the option values. * @param handle the handle of the device as returned by {@link}net_open * @param option the number of the option in question. as returned by {@link} net_get_option_descriptors * @param action the action to be performed (get/set/auto) * @param value the new value if setting. * @return the updated data of the option. * * date author reason * 09/Dec/03 am Initial version. */ protected Control_option_reply net_control_option( JSane_Net_Type_Word handle , int option , int action , JSane_Base_Type value ) throws IOException { _wire.sendWord( SANE_NET_CONTROL_OPTION ); handle._sendElement( _wire ); _wire.sendWord( option ); _wire.sendWord( action ); _wire.sendWord( value.getType() ); _wire.sendWord( value.getSize() ); if ( value.getType() != 3 ) _wire.sendWord( value.getNumberItems() ); ((JSane_Net_Transport) value)._sendElement( _wire ); Control_option_reply reply = new Control_option_reply(); reply.status = _wire.getWord(); reply.info.setValue( _wire.getWord() ); int type = _wire.getWord(); int size = _wire.getWord(); JSane_Net_Transport replyValue = (JSane_Net_Transport) JSane_Net_Type .getNewType( type , size); if ( value.getType() != 3 ) _wire.getWord(); replyValue._getElement( _wire ); reply.value = (JSane_Base_Type) replyValue; reply.resource = new JSane_Base_Type_String( _wire.getString() ); return reply; } /** * Get the parameters of the current scan. * @param handle The handle of the device to get the parameters for. * @return the data returned from saned. * * date author reason * 09/Dec/03 am Initial version. */ protected Get_Parameters_Reply net_get_parameters( JSane_Net_Type_Word handle ) throws IOException { _wire.sendWord( SANE_NET_GET_PARAMETERS ); handle._sendElement( _wire ); Get_Parameters_Reply reply = new Get_Parameters_Reply(); reply.status = _wire.getWord(); reply.params = new JSane_Net_Parameters( _wire ); return reply; } /** * Start a scan on the given device. * @param handle The handle of the device to start the scan on. * @return the data returned from the call. * * date author reason * 09/Dec/03 am Initial version. */ protected Start_Reply net_start( JSane_Base_Type_Word handle ) throws IOException { _wire.sendWord( SANE_NET_START ); _wire.sendWord( handle ); Start_Reply reply = new Start_Reply(); reply.status = _wire.getWord(); reply.port = new JSane_Net_Type_Word( _wire ); reply.byte_order = new JSane_Net_Type_Word( _wire ); reply.resource = new JSane_Net_Type_String( _wire ); return reply; } /** * Cancel the current scan. * @param handle the handle of the device to stop scanning. * * date author reason * 09/Dec/03 am Initial version. */ public void net_cancel( JSane_Net_Type_Word handle ) throws IOException { _wire.sendWord( SANE_NET_CANCEL ); handle._sendElement( _wire ); _wire.getWord(); } /** * Authorise a resource * * @param resource The resource name * @param username The username * @param password The password for the resource / username * * date author reason * 09/Dec/03 am Initial version. */ public void net_authorize( JSane_Net_Type_String resource , JSane_Net_Type_String username , JSane_Net_Type_String password ) throws IOException { _wire.sendWord( SANE_NET_AUTHORIZE ); resource._sendElement( _wire ); username._sendElement( _wire ); password._sendElement( _wire ); } /** * Last method to be called before dropping connection to saned. * No other functions should be called after this on saned * * date author reason * 09/Dec/03 am Initial version. */ protected void net_exit() throws IOException { _wire.sendWord( SANE_NET_EXIT ); // drop connection. } /** * Get the version code as used by saned. * @param major * @param minor * @param build * @return the version number as used by the sane API */ public static int SANE_VERSION_CODE( int major , int minor , int build ) { int value = (major & 0xff) << 24; value += (minor & 0xff) << 16; value += (build & 0xffff) << 0; return value; } /** * Get the hostname of saned we're connected to. * @return The name of the host we're connected to. */ public String getHostname() { return _hostname; } /** * Get the wire we're using to talk to saned * @return */ protected JSane_Wire _getWire() { return _wire; } public void exit() throws IOException { net_exit(); } /** * @return * @throws IOException * @throws JSane_Exception */ /* * Date : Dec 30, 2004 * Author : panda * Date : Author Reason * Dec 30, 2004 panda First added Updates comments */ public Vector getDevices() throws JSane_Exception , IOException { Vector vec = new Vector(); int num = this.getNumberDevices(); for ( int loop = 0; loop < num; ++loop ) { if ( getDevice( loop ) != null ) { vec.add( this.getDevice( loop ) ); } } return vec; } }